package com.jie.lanxin.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jie.lanxin.vo.ChatGptVO;
import com.jie.lanxin.response.ApiResponse;
import com.jie.lanxin.response.ChatGptResponse;
import com.jie.lanxin.response.ResponseData;
import com.jie.lanxin.response.Message;
import com.jie.lanxin.vo.VivoAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.util.*;

@Service
public class VivoGPTService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String MESSAGES_CACHE_KEY = "chat:messages:";

    public ChatGptResponse vivogpt(ChatGptVO chatGptVO) throws Exception {
        // 从ChatGptVO获取sessionId, 如果没有则生成新的sessionId
        String sessionId = chatGptVO.getSessionId();
        if (sessionId == null || sessionId.isEmpty()) {
            sessionId = UUID.randomUUID().toString();
        }

        // 从 Redis 中获取消息列表
        List<Message> messages = (List<Message>) redisTemplate.opsForValue().get(MESSAGES_CACHE_KEY + sessionId);
        if (messages == null) {
            messages = new ArrayList<>();
        }

        // 添加用户消息到消息列表
        Message userMessage = new Message("user", chatGptVO.getMessage());
        messages.add(userMessage);

        String appId = VivoAuth.appId; // 你的应用ID
        String appKey = VivoAuth.appKey; // 你的应用密钥
        String URI = "/vivogpt/completions"; // API端点的URI
        String DOMAIN = "api-ai.vivo.com.cn"; // API端点的域名
        String METHOD = "POST"; // 请求使用的HTTP方法
        UUID requestId = UUID.randomUUID(); // 生成一个唯一的请求ID
        System.out.println("requestId: " + requestId);

        // 创建一个Map来存储查询参数
        Map<String, Object> map = new HashMap<>();
        map.put("requestId", requestId.toString());
        String queryStr = mapToQueryString(map); // 将Map转换为查询字符串

        // 创建请求体数据
        Map<String, Object> data = new HashMap<>();
        data.put("messages", messages); // 添加消息列表
        data.put("model", "vivo-BlueLM-TB"); // 使用的模型
        data.put("sessionId", sessionId);
        System.out.println("sessionId: " + sessionId);

        // 生成认证头部信息
        HttpHeaders headers = generateAuthHeaders(appId, appKey, METHOD, URI, queryStr);
        headers.add("Content-Type", "application/json"); // 设置内容类型为JSON
        System.out.println("Generated Headers: " + headers);

        // 构建API请求的完整URL
        String url = String.format("http://%s%s?%s", DOMAIN, URI, queryStr);

        // 将请求体数据Map转换为JSON字符串
        String requestBodyString = new ObjectMapper().writeValueAsString(data);
        System.out.println("Request URL: " + url);
        System.out.println("Request Body: " + requestBodyString);

        // 创建一个新的RestTemplate实例以进行HTTP请求
        RestTemplate restTemplate = new RestTemplate();

        // 创建一个新的HttpHeaders对象来存储请求头部信息
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE)); // 设置内容类型为JSON

        // 将生成的头部信息逐个添加到新的HttpHeaders对象中
        for (Map.Entry<String, String> entry : headers.toSingleValueMap().entrySet()) {
            httpHeaders.add(entry.getKey(), entry.getValue());
        }

        // 创建一个HttpEntity对象来存储请求体和头部信息
        HttpEntity<String> requestEntity = new HttpEntity<>(requestBodyString, httpHeaders);

        // 发送HTTP POST请求并获取响应
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);

        // 检查响应状态并打印响应正文或错误状态
        if (response.getStatusCode() == HttpStatus.OK) {
            System.out.println("Response body: " + response.getBody());

            // 使用Jackson ObjectMapper解析响应体
            ObjectMapper objectMapper = new ObjectMapper();
            ApiResponse apiResponse = objectMapper.readValue(response.getBody(), ApiResponse.class);
            ResponseData responseData = apiResponse.getData();
            if (responseData != null) {
                String contentValue = responseData.getContent();
                System.out.println("Content value: " + contentValue);

                // 添加助手的回复到messages列表
                Message assistantMessage = new Message("assistant", contentValue);
                messages.add(assistantMessage);

                // 将更新后的messages列表存储在Redis中
                redisTemplate.opsForValue().set(MESSAGES_CACHE_KEY + sessionId, messages);

                return new ChatGptResponse(sessionId, contentValue); // 返回解析后的内容和sessionId
            } else {
                System.out.println("Response data is null");
                return new ChatGptResponse(sessionId, "Error: Response data is null");
            }
        } else {
            System.out.println("Error response: " + response.getStatusCode());
            System.out.println("Error response body: " + response.getBody());
            return new ChatGptResponse(sessionId, "Error: " + response.getStatusCode());
        }
    }

    // 将Map转换为查询字符串
    public static String mapToQueryString(Map<String, Object> map) {
        if (map.isEmpty()) {
            return ""; // 如果Map为空，返回空字符串
        }
        StringBuilder queryStringBuilder = new StringBuilder();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (queryStringBuilder.length() > 0) {
                queryStringBuilder.append("&"); // 如果查询字符串不为空，添加&符号
            }
            queryStringBuilder.append(entry.getKey());
            queryStringBuilder.append("=");
            queryStringBuilder.append(entry.getValue());
        }
        return queryStringBuilder.toString(); // 返回查询字符串
    }

    // 生成认证头部信息
    private HttpHeaders generateAuthHeaders(String appId, String appKey, String method, String uri, String queryString) throws UnsupportedEncodingException {
        HttpHeaders headers = new HttpHeaders();
        headers = VivoAuth.generateAuthHeaders(appId, appKey, method, uri, queryString);
        headers.add("Authorization", "Bearer " + appKey); // 认证头部
        headers.add("App-Id", appId); // 添加应用ID头部
        return headers;
    }
}
